#ifndef __PAPER_CONTROLLER__
#define __PAPER_CONTROLLER__

#include <QObject>
#include <QThread>
#include <QSerialPort>
#include <QMutex>

#define CB_POS_CMD						0x30
#define CB_POS_INQUIRE_CMD				0x31

class Coordinator;
class QTimer;

class PaperControl_Worker : public QObject
{
	Q_OBJECT

public:

	enum {
		PAPER_POS_0 = 0,
		PAPER_POS_1,
		PAPER_POS_2
	};

	struct SerialConfig {
		QString port;
		uint32_t baud = QSerialPort::Baud115200;
		QSerialPort::DataBits data_bits = QSerialPort::Data8;
		QSerialPort::StopBits stop_bits = QSerialPort::OneStop;
		QSerialPort::Parity parity = QSerialPort::NoParity;
	};
	typedef struct SerialConfig SerialConfig;

    PaperControl_Worker(QObject *parent = nullptr);
    ~PaperControl_Worker();

    void setSerialParam(SerialConfig param);

    uint8_t position() { return m_pos_status; };

signals:

	void status(bool status);

public slots:

	void start_work();
	void stop_work();

	void action(uint8_t act);

private slots:

	void process_cmd_resp();
	void check_status();

private:

	void transfer_cmd(QByteArray cmd);

    QByteArray rcsv_analyze(QByteArray &raw_data);
	void parse_msg(QByteArray msg);

	QByteArray parse_response(QByteArray resp);

private:

	QMutex m_mutex;

	SerialConfig m_param;
	QSerialPort *m_port;
	QTimer *m_worker_timer;
	QTimer *m_pos_check_timer;

	uint8_t m_pos_status;

	QList<QByteArray> m_cmd_list;
	QByteArray m_response;
	uint16_t m_cmd_status;
	uint16_t m_wait_time;
};

class PaperController : public QObject
{
	Q_OBJECT

public:

    PaperController(QObject *parent = nullptr);
    ~PaperController();

    PaperControl_Worker *getWorker() {
        return m_worker;
    }

signals:

	void start();
	void stop();

private:

	QThread m_worker_thread;
    PaperControl_Worker *m_worker;

    Coordinator *m_coordinator;
};

#endif
